<template>
    <div class="slider-column v-ui">
        <div class="v-ui-area">
            <div class="track track-vertical">
                <div class="bar-wrap">
                    <div class="bar" :style="`transform: scaleY(${barScaleY});`"></div>
                </div>
                <div class="thumb" :style="`transform: translateY(-${thumbOffsetY}px);`">
                    <div class="thumb-dot"></div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, watch, onMounted, nextTick } from 'vue';

const props = defineProps({
    currentPer: {
        type: Number,
        default: 0, // 默认进度百分比为 0
    },
    sliderHeight: {
        type: Number,
        default: 12, // 默认滑块高度为 12px
    },
    order: {
        type: Boolean,
        default: false, // 默认不重置
    },
});

// 定义事件
const emit = defineEmits(['changeCurrent', 'update:order']);

// 响应式变量
const isDragging = ref(false);  // 是否正在拖动
const barScaleY = ref(0);       // 滑动条的Y轴缩放百分比 0~1
const thumbOffsetY = ref(0);    // 滑块Y轴的向上偏移量 单位px

// 初始化滑块位置
const initPosition = () => {
    barScaleY.value = props.currentPer; // 设置滑动条比例
    thumbOffsetY.value = (props.sliderHeight - 12) * props.currentPer; // 计算滑块偏移
    emit('update:order', false); // 触发更新信号
};

// 初始化拖动
const initDrag = () => {
    const slider = document.querySelector('.slider-column');
    let offsetY, currPer;

    // 鼠标按下事件处理程序
    const handleMouseDown = (e) => {
        isDragging.value = true;
        offsetY = slider.getBoundingClientRect().bottom - e.clientY;
        currPer = offsetY / slider.getBoundingClientRect().height; // 计算进度比例
        barScaleY.value = currPer;
        thumbOffsetY.value = (slider.getBoundingClientRect().height - 12) * currPer;
        emit('changeCurrent', currPer); // 触发进度更新
    };

    // 移动端触摸开始事件
    const handleTouchStart = (e) => {
        isDragging.value = true;
        offsetY = slider.getBoundingClientRect().bottom - e.touches[0].clientY;
        currPer = offsetY / slider.getBoundingClientRect().height; // 计算进度比例
        barScaleY.value = currPer;
        thumbOffsetY.value = (slider.getBoundingClientRect().height - 12) * currPer;
        emit('changeCurrent', currPer); // 触发进度更新
    };

    // 鼠标移动事件处理程序
    const handleMouseMove = (e) => {
        if (!isDragging.value) return;
        offsetY = slider.getBoundingClientRect().bottom - e.clientY;
        currPer = offsetY / slider.getBoundingClientRect().height; // 计算进度比例
        // 边界值判定
        currPer = Math.max(0, currPer);
        currPer = Math.min(1, currPer);
        barScaleY.value = currPer;
        thumbOffsetY.value = (slider.getBoundingClientRect().height - 12) * currPer;
        emit('changeCurrent', currPer); // 触发进度更新
    };

    // 移动端触摸移动事件处理程序
    const handleTouchMove = (e) => {
        if (!isDragging.value) return;
        e.preventDefault(); // 防止页面滚动
        offsetY = slider.getBoundingClientRect().bottom - e.touches[0].clientY;
        currPer = offsetY / slider.getBoundingClientRect().height; // 计算进度比例
        // 边界值判定
        currPer = Math.max(0, currPer);
        currPer = Math.min(1, currPer);
        barScaleY.value = currPer;
        thumbOffsetY.value = (slider.getBoundingClientRect().height - 12) * currPer;
        emit('changeCurrent', currPer); // 触发进度更新
    };

    // 鼠标释放事件处理程序
    const handleMouseUp = () => {
        isDragging.value = false; // 停止拖动
    };

    // 移动端触摸结束事件处理程序
    const handleTouchEnd = () => {
        isDragging.value = false; // 停止拖动
    };

    // 绑定事件
    slider.addEventListener('mousedown', handleMouseDown);
    slider.addEventListener('touchstart', handleTouchStart);
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('touchmove', handleTouchMove, { passive: false });
    document.addEventListener('mouseup', handleMouseUp);
    document.addEventListener('touchend', handleTouchEnd);
};

// 监听 `order` prop 的变化
watch(() => props.order, (curr) => {
    if (curr) {
        initPosition(); // 如果 order 改变，重新初始化位置
    }
});

// 在组件挂载后初始化滑块位置和拖动功能
onMounted(() => {
    nextTick(() => {
        initPosition(); // 等待 DOM 更新后再调用初始化
        initDrag();     // 初始化拖动事件
    });
});
</script>

<style scoped>
.slider-column {
    cursor: pointer;
    height: 12px;
}

.slider-column .track {
    align-items: center;
    display: flex;
    height: 2px;
    position: relative;
    width: 100%;
}

.slider-column .track.track-vertical {
    align-items: flex-end;
    height: 100%;
    width: 2px;
}

.bar-wrap {
    background: #e7e7e7;
    border-radius: 1.5px;
    bottom: 0;
    left: 0;
    overflow: hidden;
    position: absolute;
    right: 0;
    top: 0;
}

.bar {
    background: var(--brand_pink);
    bottom: 0;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
    transform-origin: 0 100%;
}

.thumb {
    bottom: 0;
    position: relative;
    top: auto;
    cursor: pointer;
    left: -5px;
}

.thumb-dot {
    align-items: center;
    background-color: var(--brand_pink);
    border-radius: 50%;
    display: flex;
    transform: translateZ(0);
    transition: all .2s;
    vertical-align: middle;
    height: 12px;
    width: 12px;
}
</style>